/* !!! XXX DOES NOT USE BUILT-IN DETECTION FUNCTION XXX !!! */
/* alert tcp $EXTERNAL_NET any -> $HOME_NET 12175 (msg:"EXPLOIT LANDesk Management Suite QIP service heal packet buffer overflow attempt"; flow:to_server,established; content:"heal"; offset:14; depth:4; content:"sdfx"; depth:4; metadata:policy balanced-ips drop, policy security-ips drop; reference:cve,2008-2468; reference:bugtraq,31193; reference:url,community.landesk.com/support/docs/DOC-3276; classtype:attempted-admin; sid:15968; rev:1;)
*/
/*
 * Use at your own risk.
 *
 * Copyright (C) 2005-2008 Sourcefire, Inc.
 * 
 * This file is autogenerated via rules2c, by Brian Caswell <bmc@sourcefire.com>
 */


#include "sf_snort_plugin_api.h"
#include "sf_snort_packet.h"


/* declare detection functions */
int rule15968eval(void *p);

/* declare rule data structures */
/* precompile the stuff that needs pre-compiled */
/* flow:established, to_server; */
static FlowFlags rule15968flow0 = 
{
    FLOW_ESTABLISHED|FLOW_TO_SERVER
};

static RuleOption rule15968option0 =
{
    OPTION_TYPE_FLOWFLAGS,
    {
        &rule15968flow0
    }
};
#ifndef CONTENT_FAST_PATTERN
#define CONTENT_FAST_PATTERN 0
#endif
// content:"heal", offset 14, depth 4, fast_pattern; 
static ContentInfo rule15968content1 = 
{
    (uint8_t *) "heal", /* pattern (now in snort content format) */
    4, /* depth */
    14, /* offset */
    CONTENT_FAST_PATTERN|CONTENT_BUF_NORMALIZED, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule15968option1 = 
{
    OPTION_TYPE_CONTENT,
    {
        &rule15968content1
    }
};
// content:"sdfx", depth 4; 
static ContentInfo rule15968content2 = 
{
    (uint8_t *) "sdfx", /* pattern (now in snort content format) */
    4, /* depth */
    0, /* offset */
    CONTENT_BUF_NORMALIZED, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule15968option2 = 
{
    OPTION_TYPE_CONTENT,
    {
        &rule15968content2
    }
};

/* references for sid 15968 */
/* reference: bugtraq "31193"; */
static RuleReference rule15968ref1 = 
{
    "bugtraq", /* type */
    "31193" /* value */
};

/* reference: cve "2008-2468"; */
static RuleReference rule15968ref2 = 
{
    "cve", /* type */
    "2008-2468" /* value */
};

/* reference: url "community.landesk.com/support/docs/DOC-3276"; */
static RuleReference rule15968ref3 = 
{
    "url", /* type */
    "community.landesk.com/support/docs/DOC-3276" /* value */
};

static RuleReference *rule15968refs[] =
{
    &rule15968ref1,
    &rule15968ref2,
    &rule15968ref3,
    NULL
};

/* metadata for sid 15968 */
/* metadata:policy balanced-ips drop, policy security-ips drop; */

static RuleMetaData rule15968policy1 = 
{
    "policy balanced-ips drop"
};

static RuleMetaData rule15968policy2 = 
{
    "policy security-ips drop"
};

static RuleMetaData rule15968policy3 = 
{
    "policy max-detect-ips drop"
};

static RuleMetaData *rule15968metadata[] =
{
    &rule15968policy1,
    &rule15968policy2,
    &rule15968policy3,
    NULL
};

RuleOption *rule15968options[] =
{
    &rule15968option0,
    &rule15968option1,
    &rule15968option2,
    NULL
};

Rule rule15968 = {
   
   /* rule header, akin to => tcp any any -> any any               */{
       IPPROTO_TCP, /* proto */
       "$EXTERNAL_NET", /* SRCIP     */
       "any", /* SRCPORT   */
   
       0, /* DIRECTION */
       "$HOME_NET", /* DSTIP     */
   
       "12175", /* DSTPORT   */
   },
   /* metadata */
   { 
       3,  /* genid */
       15968, /* sigid */
       4, /* revision */
   
       "attempted-admin", /* classification */
       0,  /* hardcoded priority XXX NOT PROVIDED BY GRAMMAR YET! */
       "SERVER-OTHER LANDesk Management Suite QIP service heal packet buffer overflow attempt",     /* message */
       rule15968refs /* ptr to references */
       ,rule15968metadata
   },
   rule15968options, /* ptr to rule options */
   &rule15968eval, /* use the built in detection function */
   0 /* am I initialized yet? */
};


/* detection functions */
int rule15968eval(void *p) {
    const uint8_t *cursor_normal = 0, *beg_of_payload, *end_of_payload;
    SFSnortPacket *sp = (SFSnortPacket *) p;

    uint32_t MsgLen, stringOffset;

    if(sp == NULL)
        return RULE_NOMATCH;

    if(sp->payload == NULL)
        return RULE_NOMATCH;
    
    // flow:established, to_server;
    if (checkFlow(p, rule15968options[0]->option_u.flowFlags) > 0 ) {
        // content:"heal", offset 14, depth 4, fast_pattern;
        if (contentMatch(p, rule15968options[1]->option_u.content, &cursor_normal) > 0) {
            // content:"sdfx", depth 4;
            if (contentMatch(p, rule15968options[2]->option_u.content, &cursor_normal) > 0) {

                // This protocol is goofy.  stringOffset, in the payload, is little endian.
                // MsgLen, in the header, is big endian.
                // Vulnerable condition is if stringOffset is less than 0x24 or greater
                // than MsgLen.
                if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &beg_of_payload, &end_of_payload) <= 0)
                   return RULE_NOMATCH;
 
                if(end_of_payload - beg_of_payload < 38)
                   return RULE_NOMATCH;

                cursor_normal = beg_of_payload + 34;
                stringOffset = *cursor_normal++;
                stringOffset |= *cursor_normal++ << 8;
                stringOffset |= *cursor_normal++ << 16;
                stringOffset |= *cursor_normal << 24;

                //printf("stringOffset = %d (0x%08x)\n", stringOffset, stringOffset);

                if(stringOffset < 0x24)
                    return RULE_MATCH;

                cursor_normal = beg_of_payload + 4;
                MsgLen = *cursor_normal++ << 24;
                MsgLen |= *cursor_normal++ << 16;
                MsgLen |= *cursor_normal++ << 8;
                MsgLen |= *cursor_normal;

                //printf("MsgLen = %d (0x%08x)\n", MsgLen, MsgLen);

                if(stringOffset > MsgLen)
                    return RULE_MATCH;

                // Note there is also a two-byte big endian value PayloadLen at offset 12
                // and a four-byte little endian dataLen at offset 18.
                // We ignore them, because they do not seem relevant to detection.
            }
        }
    }
    return RULE_NOMATCH;
}

/*
Rule *rules[] = {
    &rule15968,
    NULL
};
*/

